package com.company.project.common.configuration;

import com.company.project.pojo.Rest;
import com.company.project.pojo.ServiceCode;
import com.company.project.common.utils.JwtUtil;
import com.fasterxml.jackson.databind.ObjectMapper;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.ExpiredJwtException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.Order;

import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.*;

@Configuration
@WebFilter(filterName ="tokenFilter", urlPatterns = "/*")
@Order(value = 1)
public class TokenFilter implements Filter {

    final Logger logger = LoggerFactory.getLogger(TokenFilter.class);

    static Set requestURI = new HashSet<>(Arrays.asList(
            "/config-file/getConfigFile", "/user/pcLogin", "/user/appLogin", "/user/logout", "/doc.html", "/swagger-resources", "/v2/api-docs","/edition/getEditon"
        )
    );

    private static final Set<String> ALLOWED_PATHS = Collections.unmodifiableSet(requestURI);

    @Override
    public void init(FilterConfig filterConfig) {
        System.out.println("init-----------filter");
    }

    @Override
    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws ServletException, IOException {
        HttpServletRequest request = (HttpServletRequest) req;
        HttpServletResponse response = (HttpServletResponse) res;
        Rest Rest = new Rest();

        String path = request.getRequestURI().substring(request.getContextPath().length()).replaceAll("[/]+$", "");
        if (ALLOWED_PATHS.contains(path)) {
            chain.doFilter(request, response);
        }else if( path.contains("/webjars/") || path.contains("/webSocket") ){
            chain.doFilter(request, response);
        }else {
            //从请求头中获取token
            String token = request.getHeader("token");
            if(token != null && !token.equals("")){
                try {
                    Claims claims = JwtUtil.parseJWT(token);

                    chain.doFilter(request, response);
                } catch (ExpiredJwtException e){
                    logger.info("token过期");
                    response.setCharacterEncoding("UTF-8");
                    Rest.setResultCodeDesc("您的token者过期了，请重新登陆！");
                    Rest.setResultCode(ServiceCode.CODE_401);
                    output(Rest, response);
                } /*catch (Exception e) {
                    e.printStackTrace();
                    chain.doFilter(request, response);
                }*/
            }else {
                logger.info("请求地址：" + path + "的token不能为空");
                response.setCharacterEncoding("UTF-8");
                Rest.setResultCodeDesc("token不能为空");
                Rest.setResultCode(ServiceCode.CODE_401);
                output(Rest, response);
            }
        }
    }

    @Override
    public void destroy() {
        System.out.println("destroy----------filter");
    }

    public void output(Rest Rest, HttpServletResponse response) {
        response.setContentType("text/html;charset=UTF-8;");
        PrintWriter out = null;
        try {
            out = response.getWriter();
            // jackson核心对象
            ObjectMapper objectMap = new ObjectMapper();
            objectMap.writeValue(out, Rest);
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            out.flush();
            out.close();
        }

    }

}